<template>
    <div id="user-behavior-analysis">
        <div class="head">
            <h1 class="title">用户行为分析</h1>
        </div>
        <div class="content trend-box">
            <el-card>
                <h3 class="title">
                    <i class="circle-icon"></i>
                    <span>系统访问走势</span>
                </h3>

                <el-radio-group v-model="systemAccessRadio" size="mini" class="title-left">
                    <el-radio-button label="流量"></el-radio-button>
                    <el-radio-button label="用户"></el-radio-button>
                </el-radio-group>

                <div class="title-right">
                    <div class="total-num">
                        {{ `总访问${systemAccessRadio == '流量' ? '次数：' + totalVisitsNum : '人数：' + totalVisitorsNum} ` }}
                    </div>
                    <el-date-picker
                        style="width: 220px; z-index:10; margin-right: 10px"
                        v-model="systemAccessDate"
                        size="mini"
                        type="daterange"
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        value-format="yyyyMMdd"
                        @change="handleDateChange($event, 'systemAccess')"
                        :clearable="false"
                        :picker-options="setEndTime"
                    >
                    </el-date-picker>
                    <el-select v-model="queryForm.unit" placeholder="请选择" size="mini" style="width: 65px; z-index:10" @change="handleUnitChange">
                        <el-option v-for="item in systemUnitData" :key="item.value" :label="item.label" :value="item.value"> </el-option>
                    </el-select>
                    <el-button size="mini" type="primary" class="export-button" @click="handleSystemExportEchart">导出图表</el-button>
                    <el-tooltip content="刷新" placement="bottom" effect="light" popper-class="monitor-tooltip">
                        <i style="z-index: 10" class="el-icon-refresh-right" @click="getSysyemAccessTrend"></i>
                    </el-tooltip>
                </div>
                <div style="height: 100%">
                    <LineChart
                        ref="systemAccessLineChart"
                        :date="queryForm"
                        :data="systemAccessLineChartData"
                        :chartName="systemAccessRadio"
                        :key="systemKey"
                    ></LineChart>
                </div>
            </el-card>
        </div>

        <div class="content table-menu-box">
            <el-card>
                <h3 class="title">
                    <i class="circle-icon"></i>
                    <span>菜单访问流量</span>
                </h3>
                <div class="title-right">
                    <div class="total-num">
                        {{ `总访问菜单数：${menuTotal} ` }}
                    </div>
                    <el-tooltip content="刷新" placement="bottom" effect="light" popper-class="monitor-tooltip">
                        <i style="z-index: 10" class="el-icon-refresh-right" @click="getTableMenuData"></i>
                    </el-tooltip>
                </div>
                <div style="height: 100%">
                    <BarChart ref="menuBarChart" chartName="menu" :date="queryForm" :data="menuChartData" :isDetail="false" />
                </div>
            </el-card>
        </div>

        <div class="content table-menu-box">
            <el-card>
                <h3 class="title">
                    <i class="circle-icon"></i>
                    <span>用户访问流量</span>
                </h3>
                <div class="title-right">
                    <div class="total-num">
                        {{ `总访问人数：${userVisitTotal} ` }}
                    </div>
                    <el-tooltip content="刷新" placement="bottom" effect="light" popper-class="monitor-tooltip">
                        <i style="z-index: 10" class="el-icon-refresh-right" @click="getTableUserData"></i>
                    </el-tooltip>
                </div>
                <div style="height: 100%">
                    <BarChart ref="userBarChart" chartName="user" :date="queryForm" :data="userChartData" :isDetail="false" />
                </div>
            </el-card>
        </div>

        <div class="content trend-box">
            <el-card>
                <h3 class="title">
                    <i class="circle-icon"></i>
                    <span>日均访问流量</span>
                </h3>
                <div class="title-right">
                    <el-date-picker
                        style="width: 220px; z-index:10; margin-right: 10px"
                        v-model="dailyVisibleDate"
                        size="mini"
                        type="daterange"
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        value-format="yyyyMMdd"
                        @change="handleDateChange($event, 'dailyVisible')"
                        :clearable="false"
                        :picker-options="setEndTimeDaily"
                    >
                    </el-date-picker>
                    <el-button size="mini" type="primary" class="export-button" @click="handleDayExportEchart">导出图表</el-button>
                    <el-tooltip content="刷新" placement="bottom" effect="light" popper-class="monitor-tooltip">
                        <i style="z-index: 10" class="el-icon-refresh-right" @click="getTableDailyData"></i>
                    </el-tooltip>
                </div>
                <div style="height: 100%">
                    <LineChart
                        ref="dailyVisibleLineChart"
                        :date="dailyQueryForm"
                        :data="dailyVisibleLineChartData"
                        chartName="dailyVisible"
                    ></LineChart>
                </div>
            </el-card>
        </div>
    </div>
</template>

<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator';
import moment from 'moment';
import LineChart from './user-behavior-analysis/line-chart.vue';
import BarChart from './user-behavior-analysis/bar-chart.vue';
import * as api from './api/user-behavior-analysis';
import { downLoadFileFormData } from '@/utils/request';
@Component({
    name: 'UserBehaviorAnalysis',
    components: {
        LineChart,
        BarChart,
    },
})
export default class UserBehaviorAnalysis extends Vue {
    systemAccessDate: any = [moment().format('yyyyMMDD'), moment().format('yyyyMMDD')]; // 系统访问日期
    dailyVisibleDate: any = [
        moment()
            .subtract(1, 'd')
            .format('yyyyMMDD'),
        moment()
            .subtract(1, 'd')
            .format('yyyyMMDD'),
    ]; // 日初访问日期段
    // 系统访问时间单位
    systemUnitData: any[] = [
        { label: '时', value: 'hour' },
        { label: '日', value: 'day' },
    ];

    chartInstanceArr: any[] = [];
    chartRef: any[] = ['systemAccessLineChart', 'menuBarChart', 'userBarChart', 'dailyVisibleLineChart'];
    systemAccessRadio: string = '流量';
    systemKey: number = -1;
    menuTotal: number = 0; // 总菜单数
    userVisitTotal: number = 0; // 用户总访问人数
    totalVisitorsNum: number = 0; // 总访问人数
    totalVisitsNum: number = 0; // 总访问次数
    menuOptions: any[] = [];
    // 折线图数据
    systemAccessLineChartData: any = {
        data: [],
        xData: [],
        title: '系统访问走势',
    };

    // 菜单数据
    menuChartData: any = {
        data: [],
        xData: [],
        title: '菜单访问流量',
    };

    // 用户
    userChartData: any = {
        name: '',
        data: [],
        xData: [],
        title: '用户访问流量',
    };

    dailyVisibleLineChartData: any = {
        name: '',
        data: [],
        xData: [],
        title: '日均访问流量',
    };

    // 查询表单
    queryForm: any = {
        endDate: moment().format('yyyyMMDD'),
        endTime: '',
        // todo
        startDate: moment().format('yyyyMMDD'),
        startTime: '',
        unit: 'hour',
    };

    // 日均查询条件
    dailyQueryForm = {
        endDate: moment()
            .subtract(1, 'd')
            .format('yyyyMMDD'),
        endTime: '',
        startDate: moment()
            .subtract(1, 'd')
            .format('yyyyMMDD'),
        startTime: '',
        unit: 'tenMinute',
    };

    // 限制选择近1年内(365天)日期
    setEndTime: any = {
        disabledDate: time => {
            const day = 360 * 24 * 3600 * 1000; // 31536000000
            // 返回小于当前日期并近一年内的日期
            return time.getTime() > Date.now() || time.getTime() < Date.now() - 8.64e7 - day;
        },
    };
    setEndTimeDaily: any = {
        disabledDate: time => {
            const day = 360 * 24 * 3600 * 1000; // 31536000000
            // 返回小于当前日期并近一年内的日期
            return time.getTime() > Date.now() - 8.64e7 || time.getTime() < Date.now() - 8.64e7 - day;
        },
    };

    @Watch('systemAccessRadio')
    changeSystemAccessRadio() {
        const obj = this.systemData.find(item => item.name == this.systemAccessRadio) || {};
        this.systemAccessLineChartData = {
            ...this.systemAccessLineChartData,
            data: obj.data,
            name: obj.name,
        };
        this.systemKey++;
        console.log(this.systemAccessLineChartData, 'this.systemAccessLineChartData');
    }

    async mounted() {
        // this.menuOptions = await api.getUserBehaviorMenuSelect();
        // console.log(this.menuOptions, 'menuOptions');

        this.getAllChartsData();
        this.chartRef.forEach(ele => {
            this.chartInstanceArr.push((this.$refs[ele] as any).chartInstance);
        });
        console.log(this.chartInstanceArr, 'chartInstanceArr');
        window.addEventListener('resize', this.screenAdapter);
        this.screenAdapter();

        this.timer && clearInterval(this.timer);
        this.setTimer();
    }

    // 一分钟刷新一次
    setTimer() {
        const funcArr = [this.getSysyemAccessTrend, this.getTableMenuData, this.getTableUserData, this.getTableDailyData];
        this.timer = setInterval(() => {
            for (let index = 0; index < funcArr.length; index++) {
                (function(t) {
                    setTimeout(function() {
                        funcArr[index]('autoRefresh');
                    }, 200 * t); // 还是每200ms执行一次，不是累加的
                })(index);
            }
        }, 60 * 1000);
    }

    screenAdapter() {
        const titleFontSize = ((this.$refs.systemAccessLineChart as any).offsetWidth / 100) * 5.6;
        // 分辨率变化图表配置
        const adapterOption = {
            axisLabel: {
                textStyle: {
                    fontSize: titleFontSize,
                },
            },
            // 柱状条目
            series: [],
        };
        this.chartInstanceArr.forEach(ele => {
            ele.setOption(adapterOption);
            ele.resize();
        });
    }

    // 处理日期变化
    handleDateChange(date: any[], type: string) {
        console.log(date, type);
        let unit = 'hour';
        let startDate = '';
        let endDate = '';
        let unitData = [
            { label: '时', value: '1' },
            { label: '日', value: '2' },
        ];
        if (date && date.length) {
            startDate = date[0];
            endDate = date[1];
        }
        if (type == 'dailyVisible') {
            this.dailyQueryForm.startDate = startDate;
            this.dailyQueryForm.endDate = endDate;
            this.getTableDailyData();
        } else if (type == 'systemAccess') {
            let days = moment(endDate, 'YYYYMMDD').diff(moment(startDate, 'YYYYMMDD'), 'days');
            let months = moment(endDate, 'YYYYMMDD').diff(moment(startDate, 'YYYYMMDD'), 'months');
            let years = moment(endDate, 'YYYYMMDD').diff(moment(startDate, 'YYYYMMDD'), 'years');

            if (days == 0) {
                // 开始结束日期为同一天
                unitData = [
                    { label: '时', value: 'hour' },
                    { label: '日', value: 'day' },
                ];
                unit = 'hour';
            } else if (days > 0 && months == 0) {
                // 所选的日期区间超出一天小于一个月
                unitData = [
                    { label: '日', value: 'day' },
                    { label: '月', value: 'month' },
                ];
                unit = 'day';
            } else if (months > 0 && years == 0) {
                // 所选的日期区间超出一个月小于一年
                unitData = [
                    { label: '月', value: 'month' },
                    { label: '年', value: 'year' },
                ];
                unit = 'month';
            }
            this.queryForm.startDate = startDate;
            this.queryForm.endDate = endDate;
            this.queryForm.unit = unit;
            this.systemUnitData = unitData;
            this.handleUnitChange();
        }
    }

    // 所有图的方法
    getAllChartsData() {
        this.getSysyemAccessTrend();
        this.getTableMenuData();
        this.getTableUserData();
        this.getTableDailyData();
    }

    systemData: any = [];
    // 系统访问走势
    getSysyemAccessTrend(operateType?: string) {
        api.queryUserBehaviorTrend({ ...this.queryForm }, operateType)
            .then((res: any) => {
                this.systemData = res.trafficLineChart.data;
                const obj = this.systemData.find(item => item.name == this.systemAccessRadio) || {};
                this.systemAccessLineChartData = {
                    data: obj.data,
                    name: obj.name,
                    xData: res.trafficLineChart.xData,
                    title: this.systemAccessLineChartData.title,
                };

                this.totalVisitorsNum = res.totalVisitorsNum;
                this.totalVisitsNum = res.totalVisitsNum;
                console.log(this.systemAccessLineChartData, 'this.systemAccessLineChartData');
            })
            .catch(() => {});
    }

    // 菜单访问流量
    getTableMenuData(operateType?: string) {
        api.queryUserBehaviorMenuTrend({ ...this.queryForm }, operateType)
            .then((res: any) => {
                // todo
                const obj = res.menuBarChart?.data[0];
                this.menuChartData.data = obj?.data;
                this.menuChartData.name = obj?.name;
                this.menuChartData.xData = res?.menuBarChart.xData;
                this.menuTotal = res.totalAccessMenuNum;
            })
            .catch(() => {});
    }

    // 用户访问流量
    getTableUserData(operateType?: string) {
        api.queryUserBehaviorUserTrend({ ...this.queryForm }, operateType)
            .then((res: any) => {
                const actualData = res.userBarChart;
                this.userChartData.data = actualData.data[0].data;
                this.userChartData.name = actualData.data[0].name;
                this.userChartData.xData = actualData.xData;
                this.userVisitTotal = res.totalVisitorsNum;
            })
            .catch(() => {});
    }

    // 日均访问流量
    getTableDailyData(operateType?: string) {
        api.queryUserBehaviorDailyTrend({ ...this.dailyQueryForm }, operateType)
            .then((res: any) => {
                this.dailyVisibleLineChartData.data = res.data[0].data;
                this.dailyVisibleLineChartData.name = res.data[0].name;
                this.dailyVisibleLineChartData.xData = res.xData;
            })
            .catch(() => {});
    }

    // 日期单位
    handleUnitChange() {
        this.getSysyemAccessTrend();
        this.getTableMenuData();
        this.getTableUserData();
    }

    // 导出图表事件
    handleSystemExportEchart() {
        let param = {
            pixelRatio: 2,
            backgroundColor: '#fff',
            excludeComponents: ['toolbox'],
        };

        let lineChartImgUrl = this.chartInstanceArr[0].getDataURL(param);
        let barChartImgUrlMenu = this.chartInstanceArr[1].getDataURL(param);
        let barChartImgUrlUser = this.chartInstanceArr[2].getDataURL(param);

        let chart1 = this.convertBase64UrlToBlob(lineChartImgUrl);
        let chart2 = this.convertBase64UrlToBlob(barChartImgUrlMenu);
        let chart3 = this.convertBase64UrlToBlob(barChartImgUrlUser);
        let formData = new FormData();
        for (const key in this.queryForm) {
            formData.append(key, this.queryForm[key]);
        }
        formData.append(
            'filename',
            `(${this.queryForm.startDate}-${this.queryForm.endDate})系统访问走势-${moment().format('yyyyMMDD')}-${moment().format('HHmmss')}`
        );
        formData.append('files', chart1);
        formData.append('files', chart2);
        formData.append('files', chart3);

        downLoadFileFormData({
            url: '/userBehavior/trend/export',
            method: 'post',
            data: formData,
            loading: true,
            loadingMsg: '正在准备导出，请稍后··· ···',
        });
    }

    // 日均导出
    handleDayExportEchart() {
        let param = {
            pixelRatio: 2,
            backgroundColor: '#fff',
            excludeComponents: ['toolbox'],
        };

        let lineChartImgUrl = this.chartInstanceArr[3].getDataURL(param);

        let chart1 = this.convertBase64UrlToBlob(lineChartImgUrl);
        let formData = new FormData();
        for (const key in this.dailyQueryForm) {
            formData.append(key, this.dailyQueryForm[key]);
        }
        formData.append('files', chart1);
        formData.append(
            'filename',
            `(${this.dailyQueryForm.startDate}-${this.dailyQueryForm.endDate})日均访问流量-${moment().format('yyyyMMDD')}-${moment().format(
                'HHmmss'
            )}`
        );

        downLoadFileFormData({
            url: '/userBehavior/systemLog/export',
            method: 'post',
            data: formData,
            loading: true,
            loadingMsg: '正在准备导出，请稍后··· ···',
        });
    }

    /*
     * 将base64转换成可用formdata提交的文件
     * @param {String} urlData base64的url
     */
    convertBase64UrlToBlob(urlData) {
        // 去掉url的头，并转换为byte
        var bytes = window.atob(urlData.split(',')[1]);
        // 处理异常,将ascii码小于0的转换为大于0
        var ab = new ArrayBuffer(bytes.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i);
        }
        return new Blob([ab], { type: 'image/png' });
    }

    timer = null;
    beforeDestroy() {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        }
    }

    destroyed() {
        window.removeEventListener('resize', this.screenAdapter);
    }
}
</script>

<style lang="scss" scoped>
#user-behavior-analysis {
    width: 100%;
    height: 100%;
    min-width: 1400px;

    .head {
        width: 100%;
        height: 60px;
        background-image: url('./images/title.png');
        background-size: 100%;

        .title {
            font-size: 24px;
            font-weight: 600;
            color: #107fff;
            line-height: 33px;
            letter-spacing: 20px;
            text-align: center;
            height: 100%;
            line-height: 60px;
        }
    }

    .content {
        padding: 0 10px 5px 10px;

        .title {
            position: absolute;
            height: 25px;
            line-height: 25px;
            overflow: hidden;

            > span {
                padding-left: 25px;
                font-size: 16px;
                font-weight: bold;
            }
        }
        .title-left {
            position: absolute;
            left: 10%;
            z-index: 1000;
        }
        .title-right {
            display: flex;
            align-items: center;
            position: absolute;
            right: 1%;
            > i {
                font-size: 22px;
                padding: 0 3px;
                cursor: pointer;
                color: #48c682;
            }

            // i:hover {
            //     color: #107fff;
            // }
            .total-num {
                margin-right: 20px;
                color: #fff;
                background-color: #578bec;
                padding: 5px 15px;
                font-size: 14px;
                background: url('./images/item-monitor-total.png');
                background-size: 100% 30px;
                background-repeat: no-repeat;
            }
            .export-button {
                margin: 0 10px;
                z-index: 10;
            }
            .el-button {
                border-radius: 9px;
                padding-top: 6px;
                padding-bottom: 6px;
            }
        }

        /deep/ .el-card {
            height: 100%;
        }

        /deep/ .el-card__body {
            padding: 10px;
            height: 100%;
            position: relative;
        }
        /deep/ .el-range-separator {
            width: 10% !important;
        }
    }

    .trend-box {
        height: 23vh;
        min-height: 200px;
    }

    .table-menu-box {
        height: 23vh;
        min-height: 200px;
    }
}

/deep/ .el-radio-button__inner {
    border-radius: 4px !important;
    border-left: 1px solid #dcdfe6;
    margin-right: 20px;
}
</style>
<style>
.el-tooltip__popper {
    margin: 5px !important;
}

.monitor-tooltip {
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.3) !important;
    background-color: rgba(255, 255, 255, 0.8) !important;
    border-color: rgba(0, 0, 0, 0.1) !important;
    color: rgba(0, 0, 0, 0.65);
    border-width: 0px;
    padding: 5px 10px;
}

.monitor-tooltip .popper__arrow {
    display: none;
}
</style>
